allow events to expire; fix spec

Andrew Cantino лет %!s(int64=10): %!d(string=назад)
Родитель
Сommit
86bcc465a4
6 измененных файлов с 86 добавлено и 18 удалено
  1. 4 0
      app/models/event.rb
  2. 35 16
      bin/schedule.rb
  3. 6 0
      db/migrate/20131105063248_add_expires_at_to_events.rb
  4. 3 1
      db/schema.rb
  5. 1 1
      spec/models/agent_spec.rb
  6. 37 0
      spec/models/event_spec.rb

+ 4 - 0
app/models/event.rb

@@ -21,4 +21,8 @@ class Event < ActiveRecord::Base
21 21
   def reemit!
22 22
     agent.create_event :payload => payload, :lat => lat, :lng => lng
23 23
   end
24
+
25
+  def self.cleanup_expired!
26
+    Event.where("expires_at IS NOT NULL AND expires_at < ?", Time.now).delete_all
27
+  end
24 28
 end

+ 35 - 16
bin/schedule.rb

@@ -11,40 +11,59 @@ end
11 11
 require 'rufus/scheduler'
12 12
 
13 13
 class HuginnScheduler
14
-  def run_schedule(time, mutex)
15
-    ActiveRecord::Base.connection_pool.with_connection do
16
-      mutex.synchronize do
17
-        puts "Queuing schedule for #{time}"
18
-        Agent.delay.run_schedule(time)
19
-      end
14
+  attr_accessor :mutex
15
+
16
+  def run_schedule(time)
17
+    with_mutex do
18
+      puts "Queuing schedule for #{time}"
19
+      Agent.delay.run_schedule(time)
20
+    end
21
+  end
22
+
23
+  def propagate!
24
+    with_mutex do
25
+      puts "Queuing event propagation"
26
+      Agent.delay.receive!
20 27
     end
21 28
   end
22 29
 
23
-  def propagate!(mutex)
30
+  def cleanup_expired_events!
31
+    with_mutex do
32
+      puts "Running event cleanup"
33
+      Event.delay.cleanup_expired!
34
+    end
35
+  end
36
+
37
+  def with_mutex
24 38
     ActiveRecord::Base.connection_pool.with_connection do
25 39
       mutex.synchronize do
26
-        puts "Queuing event propagation"
27
-        Agent.delay.receive!
40
+        yield
28 41
       end
29 42
     end
30 43
   end
31 44
 
32 45
   def run!
33
-    mutex = Mutex.new
46
+    self.mutex = Mutex.new
34 47
 
35 48
     rufus_scheduler = Rufus::Scheduler.new
36 49
 
37 50
     # Schedule event propagation.
38 51
 
39 52
     rufus_scheduler.every '1m' do
40
-      propagate!(mutex)
53
+      propagate!
54
+    end
55
+
56
+    # Schedule event cleanup.
57
+
58
+    rufus_scheduler.cron "0 0 * * * America/Los_Angeles" do
59
+      cleanup_expired_events!
41 60
     end
42 61
 
43 62
     # Schedule repeating events.
44 63
 
45 64
     %w[2m 5m 10m 30m 1h 2h 5h 12h 1d 2d 7d].each do |schedule|
46 65
       rufus_scheduler.every schedule do
47
-        run_schedule "every_#{schedule}", mutex
66
+        run_schedule "every_#{schedule}"
48 67
       end
49 68
     end
50 69
 
@@ -54,13 +73,13 @@ class HuginnScheduler
54 73
     24.times do |hour|
55 74
       rufus_scheduler.cron "0 #{hour} * * * America/Los_Angeles" do
56 75
         if hour == 0
57
-          run_schedule "midnight", mutex
76
+          run_schedule "midnight"
58 77
         elsif hour < 12
59
-          run_schedule "#{hour}am", mutex
78
+          run_schedule "#{hour}am"
60 79
         elsif hour == 12
61
-          run_schedule "noon", mutex
80
+          run_schedule "noon"
62 81
         else
63
-          run_schedule "#{hour - 12}pm", mutex
82
+          run_schedule "#{hour - 12}pm"
64 83
         end
65 84
       end
66 85
     end

+ 6 - 0
db/migrate/20131105063248_add_expires_at_to_events.rb

@@ -0,0 +1,6 @@
1
+class AddExpiresAtToEvents < ActiveRecord::Migration
2
+  def change
3
+    add_column :events, :expires_at, :datetime
4
+    add_index :events, :expires_at
5
+  end
6
+end

+ 3 - 1
db/schema.rb

@@ -11,7 +11,7 @@
11 11
 #
12 12
 # It's strongly recommended to check this file into your version control system.
13 13
 
14
-ActiveRecord::Schema.define(:version => 20130819160603) do
14
+ActiveRecord::Schema.define(:version => 20131105063248) do
15 15
 
16 16
   create_table "agent_logs", :force => true do |t|
17 17
     t.integer  "agent_id",                         :null => false
@@ -67,9 +67,11 @@ ActiveRecord::Schema.define(:version => 20130819160603) do
67 67
     t.text     "payload",    :limit => 16777215
68 68
     t.datetime "created_at",                                                     :null => false
69 69
     t.datetime "updated_at",                                                     :null => false
70
+    t.datetime "expires_at"
70 71
   end
71 72
 
72 73
   add_index "events", ["agent_id", "created_at"], :name => "index_events_on_agent_id_and_created_at"
74
+  add_index "events", ["expires_at"], :name => "index_events_on_expires_at"
73 75
   add_index "events", ["user_id", "created_at"], :name => "index_events_on_user_id_and_created_at"
74 76
 
75 77
   create_table "links", :force => true do |t|

+ 1 - 1
spec/models/agent_spec.rb

@@ -186,7 +186,7 @@ describe Agent do
186 186
         }
187 187
         Agent.async_check(agents(:bob_weather_agent).id)
188 188
         lambda {
189
-          Agent.receive!
189
+          Agent.async_receive(agents(:bob_rain_notifier_agent).id, [agents(:bob_weather_agent).events.last.id])
190 190
         }.should raise_error
191 191
         log = agents(:bob_rain_notifier_agent).logs.first
192 192
         log.message.should =~ /Exception/

+ 37 - 0
spec/models/event_spec.rb

@@ -16,4 +16,41 @@ describe Event do
16 16
       Event.last.created_at.should be_within(1).of(Time.now)
17 17
     end
18 18
   end
19
+
20
+  describe ".cleanup_expired!" do
21
+    it "removes any Events whose expired_at date is non-null and in the past" do
22
+      event = Event.new
23
+      event.agent = agents(:jane_weather_agent)
24
+      event.expires_at = 2.hours.from_now
25
+      event.save!
26
+
27
+      current_time = Time.now
28
+      stub(Time).now { current_time }
29
+
30
+      Event.cleanup_expired!
31
+      Event.find_by_id(event.id).should_not be_nil
32
+      current_time = 119.minutes.from_now
33
+      Event.cleanup_expired!
34
+      Event.find_by_id(event.id).should_not be_nil
35
+      current_time = 2.minutes.from_now
36
+      Event.cleanup_expired!
37
+      Event.find_by_id(event.id).should be_nil
38
+    end
39
+
40
+    it "doesn't touch Events with no expired_at" do
41
+      event = Event.new
42
+      event.agent = agents(:jane_weather_agent)
43
+      event.expires_at = nil
44
+      event.save!
45
+
46
+      current_time = Time.now
47
+      stub(Time).now { current_time }
48
+
49
+      Event.cleanup_expired!
50
+      Event.find_by_id(event.id).should_not be_nil
51
+      current_time = 2.days.from_now
52
+      Event.cleanup_expired!
53
+      Event.find_by_id(event.id).should_not be_nil
54
+    end
55
+  end
19 56
 end